package pro.cherish.smartfile.util;

import lombok.extern.slf4j.Slf4j;

import java.io.*;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

@Slf4j
public class Md5Util {

    /**
     * 生成文件的md5校验值(对应前端 spark-md5.js)
     *
     * @param file
     * @return
     * @throws IOException
     */
    public static String file2Md5(File file) throws IOException, NoSuchAlgorithmException {
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        byte[] buffer = new byte[1024];
        int length;
        FileInputStream fileInputStream = new FileInputStream(file);
        while ((length = fileInputStream.read(buffer, 0, 1024)) != -1) {
            md5.update(buffer, 0, length);
        }
        byte[] digest = md5.digest();
        fileInputStream.close();
        return byteArrayToHex(digest);
    }

    /**
     * 字节数组转md5
     *
     * @param byteArray
     * @return
     */
    private static String byteArrayToHex(byte[] byteArray) {
        // 首先初始化一个字符数组，用来存放每个16进制字符
        char[] hexDigits = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
        // new一个字符数组，这个就是用来组成结果字符串的（解释一下：一个byte是八位二进制，也就是2位十六进制字符（2的8次方等于16的2次方））
        char[] resultCharArray = new char[byteArray.length * 2];
        // 遍历字节数组，通过位运算（位运算效率高），转换成字符放到字符数组中去
        int index = 0;
        for (byte b : byteArray) {
            resultCharArray[index++] = hexDigits[b >>> 4 & 0xf];
            resultCharArray[index++] = hexDigits[b & 0xf];
        }
        // 字符数组组合成字符串返回
        return new String(resultCharArray);
    }


    /**
     * 字节数组转md5
     *
     * @param bytes
     * @return
     * @throws NoSuchAlgorithmException
     */
    public static String byteArray2Md5(byte[] bytes) throws NoSuchAlgorithmException {
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        md5.update(bytes, 0, bytes.length);
        byte[] digest = md5.digest();
        return byteArrayToHex(digest);
    }

    public static void main(String[] args) throws IOException, NoSuchAlgorithmException {
//        File file = new File("O:\\temp\\smart_file\\temp\\fb207014d73d74660765b8bbb408ee61\\1.data");
//        File file = new File("O:\\temp\\smart_file\\test\\1.txt");
        File file = new File("O:\\录屏\\2020-12-09-21-50-48.mp4");
        String s = Md5Util.file2Md5(file);
        log.error(s);
        byte[] bytes = toByteArray(file);
//        String str2 = new String(bytes, "UTF-8");
//        log.error(str2);
        String s1 = Md5Util.byteArray2Md5(bytes);
        log.error(s1);


    }

    public static byte[] toByteArray(File file) throws IOException {
        File f = file;
        if (!f.exists()) {
            throw new FileNotFoundException("file not exists");
        }
        ByteArrayOutputStream bos = new ByteArrayOutputStream((int) f.length());
        BufferedInputStream in = null;
        try {
            in = new BufferedInputStream(new FileInputStream(f));
            int buf_size = 1024;
            byte[] buffer = new byte[buf_size];
            int len = 0;
            while (-1 != (len = in.read(buffer, 0, buf_size))) {
                bos.write(buffer, 0, len);
            }
            return bos.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        } finally {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
            bos.close();
        }
    }
}